package com.luge.utils;

import android.media.MediaPlayer;
import android.media.MediaPlayer.OnCompletionListener;
import android.media.MediaPlayer.OnErrorListener;
import android.media.MediaPlayer.OnPreparedListener;

public class SongPlayer implements SongPlayerInterface, OnCompletionListener,
		OnPreparedListener, OnErrorListener {
	private static final int STATE_IDLE = 0;
	private static final int STATE_PREPARING = 1;
	private static final int STATE_PLAYING = 3;
	private static final int STATE_PAUSED = 4;

	private static SongPlayer audioPlayer;
	private MediaPlayer mMediaPlayer;
	private SongPlayCallBack audioPlayCallBack;
	private int playState = STATE_IDLE;
	private String audioPath;

	private SongPlayer() {

	}

	public static SongPlayer getInstance() {
		if (audioPlayer == null) {
			audioPlayer = new SongPlayer();
		}
		return audioPlayer;
	}

	public void initMediaPlayer() {
		if (mMediaPlayer == null) {
			mMediaPlayer = new MediaPlayer();
			mMediaPlayer.setOnCompletionListener(this);
			mMediaPlayer.setOnErrorListener(this);
			mMediaPlayer.setOnPreparedListener(this);
			playState = STATE_IDLE;
		}
	}

	@Override
	public void play() {
		try {
			if (playState == STATE_IDLE) {
				initMediaPlayer();
				mMediaPlayer.reset();
				mMediaPlayer.setDataSource(audioPath);
				mMediaPlayer.prepareAsync();
				playState = STATE_PREPARING;
				if (audioPlayCallBack != null) {
					audioPlayCallBack.prepared();
				}
			} else if (playState == STATE_PAUSED) {
				mMediaPlayer.start();
				playState = STATE_PLAYING;
				if (audioPlayCallBack != null) {
					audioPlayCallBack.play();
				}
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	@Override
	public void pause() {
		if (playState == STATE_PLAYING) {
			mMediaPlayer.pause();
			playState = STATE_PAUSED;
			if (audioPlayCallBack != null) {
				audioPlayCallBack.pause();
			}
		} else if (playState == STATE_PREPARING) {
			mMediaPlayer.reset();
			playState = STATE_IDLE;
			if (audioPlayCallBack != null) {
				audioPlayCallBack.stop();
			}
		}
	}

	@Override
	public void stop() {
		if (mMediaPlayer != null) {
			mMediaPlayer.reset();
			mMediaPlayer.release();
			mMediaPlayer = null;
		}
		if (audioPlayCallBack != null) {
			audioPlayCallBack.stop();
		}
		playState = STATE_IDLE;
	}

	public String getAudioPath() {
		return audioPath;
	}

	public void setAudioPath(String audioPath) {
		this.audioPath = audioPath;
	}

	@Override
	public void seekTo(int index) {
		if (playState == STATE_IDLE) {

		} else if (playState == STATE_PREPARING) {

		} else if (playState == STATE_PAUSED) {

		} else if (playState == STATE_PLAYING) {

		}
	}

	@Override
	public int getDuration() {
		if (mMediaPlayer != null && playState == STATE_PLAYING) {
			return mMediaPlayer.getDuration();
		}
		return -1;
	}

	@Override
	public int getPosition() {
		if (mMediaPlayer != null && playState == STATE_PLAYING) {
			return mMediaPlayer.getCurrentPosition();
		}
		return -1;
	}

	@Override
	public boolean onError(MediaPlayer mp, int what, int extra) {
		switch (what) {
		case MediaPlayer.MEDIA_ERROR_SERVER_DIED:
			Helper.log("Media server died");
			break;
		case MediaPlayer.MEDIA_ERROR_UNKNOWN:
			Helper.log("media player error_unknown");
			break;
		case MediaPlayer.MEDIA_ERROR_NOT_VALID_FOR_PROGRESSIVE_PLAYBACK:
			Helper.log("URL is not valid");
			break;
		}
		return false;
	}

	@Override
	public void onCompletion(MediaPlayer mp) {
		stop();
	}

	@Override
	public void onPrepared(MediaPlayer mp) {
		try {
			if (playState != STATE_IDLE) {
				mMediaPlayer.start();
				if (audioPlayCallBack != null) {
					audioPlayCallBack.play();
				}
				playState = STATE_PLAYING;
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	public boolean getPlayerState() {
		if (playState == STATE_PLAYING || playState == STATE_PREPARING) {
			return true;
		} else {
			return false;
		}
	}

	@Override
	public void setPlayCallBack(SongPlayCallBack audioPlayCallBack) {
		this.audioPlayCallBack = audioPlayCallBack;
	}

	public interface SongPlayCallBack {
		void play();

		void pause();

		void stop();

		void prepared();
	}
}
